package com.auditlog.sql.parser;

import cn.hutool.core.collection.CollectionUtil;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.JdbcParameter;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
import net.sf.jsqlparser.util.deparser.SelectDeParser;
import net.sf.jsqlparser.util.deparser.StatementDeParser;

import java.util.ArrayList;
import java.util.List;

/**
 * 工具类
 * @author Zhiyang.Zhang
 * @date 2022/11/13 21:05
 * @version 1.0
 */
public class JSqlParserSupport {

    // TODO Oracle union all加锁出现问题
    public String expressions2Sql(List<ExpressionList> expressionList) {
        StringBuilder builder = new StringBuilder();
        int index = 0;
        for (ExpressionList list : expressionList) {
            String s = expressions2Sql(list);
            if (index != expressionList.size() - 1) {
                builder.append(s).append(" union all ");
            } else {
                builder.append(s);
            }
            index++;
        }
        return builder.toString();
    }

    /**
     * 获取表达式中的sql，防止有sql函数之类的（一个ExpressionList代表一个values后面的一行数据）
     *
     * @param expressionList
     * @return: java.lang.String
     */
    public String expressions2Sql(ExpressionList expressionList) {
        StringBuilder builder = new StringBuilder();
        builder.append("select ");
        List<Expression> expressions = expressionList.getExpressions();
        int index = 0;
        for (Expression expression : expressions) {
            if (index == expressions.size() - 1) {
                builder.append(expression.toString()).append(" from dual ");
            } else {
                builder.append(expression.toString()).append(",");
            }
            index++;
        }
        return builder.toString();
    }


    /**
     * 获取所有values(),()中的所有占位符下标
     *
     * @param multiExpressionList
     * @return: java.util.List<java.lang.Integer>
     */
    public List<Integer> multiExpressionListPlaceHolderIndex(MultiExpressionList multiExpressionList) {
        List<Integer> indexes = new ArrayList<>();
        multiExpressionList.getExpressionLists().forEach(expressionList -> indexes.addAll(expressionListPlaceHolderIndex(expressionList.getExpressions())));
        return indexes;
    }


    /**
     * 获取select语句中的占位符
     *
     * @param select
     * @return: java.util.List<java.lang.Integer>
     */
    public List<Integer> selectPlaceHolderIndex(Select select) {
        List<Integer> index = new ArrayList<>();
        ExpressionDeParser expressionDeParser = new ExpressionDeParser() {
            @Override
            public void visit(JdbcParameter jdbcParameter) {
                super.visit(jdbcParameter);
                index.add(jdbcParameter.getIndex());
            }
        };
        StringBuilder builder = new StringBuilder();
        SelectDeParser selectDeParser = new SelectDeParser(expressionDeParser, builder);
        select.accept(new StatementDeParser(expressionDeParser, selectDeParser, builder));
        return index;
    }

    /**
     * 获取表达式的占位符下标
     *
     * @param expressions expression集合
     * @return: java.util.List<java.lang.Integer>
     */
    public List<Integer> expressionListPlaceHolderIndex(List<Expression> expressions) {
        List<Integer> indexes = new ArrayList<>();
        if (expressions == null || CollectionUtil.isEmpty(expressions)) {
            return indexes;
        }
        expressions.forEach(expression -> {
            expression.accept(new ExpressionDeParser() {

                @Override
                public void visit(JdbcParameter jdbcParameter) {
                    super.visit(jdbcParameter);
                    indexes.add(jdbcParameter.getIndex());
                }
            });
        });
        return indexes;
    }
}
